import {
	EVENT_PICK_SHOW, EVENT_BAN_HIDE, EVENT_SHOW, EVENT_SEAT_INFO_HIDE, EVENT_TEAM_HIDE,
	EVENT_PANEL_CONTENT, EVENT_ARROW, EVENT_TIMER_PAUSE, EVENT_COMPLETE } from './events';
import { BanPick, buildAction } from './banPick';
import { seats } from './events';

class Lottery {
	/**
	 * @param {BanPick} bp 
	 */
	constructor(context, bp) {
		this.context = context;
		this.bp = bp;
		this.roomId = -1;
		this.danmaku = null;
		/** 是否开始抽奖了 */ this.start = false;
		/** 抽奖说的话是啥 */ this.words = {
			PL1 : "111",
			PL2 : "222",
			PL3 : "333",
			PL4 : "444",
			PL5 : "555",
			PR1 : "666",
			PR2 : "777",
			PR3 : "888",
			PR4 : "999",
			PR5 : "000",
		};
		this.pool = new Pool();
	}

	collectInfo() {
		return {
			roomId : this.roomId,
			words : this.words,
			pool : this.pool.collectInfo(),

			start : this.start,
		}
	}

	load(param) {
		if (param.words) {
			Object.assign(this.words, param.words);
		}
	}

	initBanPick() {
		this.bp.assetsLoad({
			team : ['', ''],
			desc : ['', ''],
			score: ['', ''],
			patch: '弹幕抽奖模式',
			players: this.words
		});
		[
			buildAction(EVENT_SHOW),
			buildAction(EVENT_TEAM_HIDE),
			buildAction(EVENT_PICK_SHOW, 0, {seats: seats.pick.left.concat(seats.pick.right)}),
			buildAction(EVENT_BAN_HIDE),
			buildAction(EVENT_PANEL_CONTENT, 0, {content: 'patch'}),
			buildAction(EVENT_TIMER_PAUSE, 0, {pause: true}),
			buildAction(EVENT_ARROW, 0, {seats: []}),
			buildAction(EVENT_SEAT_INFO_HIDE, 0, {seats: seats.pick.left.concat(seats.pick.right)}),
		].forEach(a => a.handle(this.bp));
	}

	/**
	 * @param {number} roomId 直播房间号
	 */
	connect(roomId) {
		this.roomId = roomId;
		this.danmaku = new this.context.Danmaku(roomId);
		this.danmaku.createSource()
			.then(() => this.danmaku.openSource())
			.then(() => {
				this.danmaku.onDanmuReceived = (o) => this.onDanmuReceived(o);
			});
	}

	open() {
		if (!this.danmaku) return;
		this.start = true;
		this.updateSeatPlayerTitle();
		buildAction(EVENT_ARROW, 0, {seats: seats.pick.left.concat(seats.pick.right)}).handle(this.bp);
	}

	close() {
		this.start = false;
		buildAction(EVENT_ARROW, 0, {seats: []}).handle(this.bp);
	}

	pick(seatName) {
		buildAction(EVENT_COMPLETE, 0, {seats: [seatName]}).handle(this.bp);
		const pair = this.pool.pick(seatName);
		console.log("抽了", pair);
		this.updateSeatPlayerTitle();
		// 显示抽中的人 TODO
		return pair;
	}

	onDanmuReceived(danmu) {
		if (!this.start) {
			return;
		}

		const uid = danmu.uId;
		const word = danmu.text;
		let toSeatName = null;
		const seatArray = seats.pick.left.concat(seats.pick.right);
		for (let index in seatArray) {
			const seatName = seatArray[index];
			if (word === this.words[seatName]) {
				toSeatName = seatName;
				break;
			}
		}

		if (toSeatName == null) {
			return;
		}
		this.pool.push(toSeatName, uid, danmu.uName);
		this.updateSeatPlayerTitle();
		buildAction(EVENT_COMPLETE, 0, {seats: [toSeatName]}).handle(this.bp);
	}

	/**
	 * 每个 pick seat 的文字是: `${word}   |${count}`
	 */
	updateSeatPlayerTitle() {
		const words = this.words;
		const events = {};

		this.pool.count()
				.forEach(entry => events[entry.seatName] = `${words[entry.seatName]}     |${entry.count} 人`);

		this.bp.assetsLoad({
			players: events
		});
	}
}

/**
 * 每一个 pick seat 就是一个奖池, 里面装了人. Pool 里面维护一个双向映射关系, 是 uid 和 seat.
 */
class Pool {
	/** @type {Pair[]} */
	pairs = [];

	clear() {
		this.pairs = [];
	}
	/**
	 * @param {string} seatName 
	 * @param {number} uid 
	 * @param {string} uname 
	 */
	push(seatName, uid, uname) {
		let pair = this.pairs.find(p => p.uid === uid);
		if (pair == null) {
			this.pairs.push(new Pair(seatName, uid, uname));
		} else {
			pair.seatName = seatName;
		}
	}

	//
	collectInfo() {
		return {
			pairs : this.pairs
		};
	}

	findBySeat(seatName) {
		return this.pairs.filter(p => p.seatName === seatName);
	}

	pick(seatName) {
		const array = this.findBySeat(seatName);
		if (array.length == 0) {
			// 显示没抽到
			return null;
		}
		const pair = array[Math.floor(Math.random() * array.length)];

		let i = this.pairs.findIndex(p => p.uid === pair.uid);
		this.pairs.splice(i, 1);
		return pair;
	}

	count() {
		// 每个 seat 的 count
		return seats.pick.left.concat(seats.pick.right)
				.map(seatName => { return { seatName, count : this.findBySeat(seatName).length };});
	}
}

class Pair {
	/**
	 * @param {string} seatName 
	 * @param {number} uid 
	 * @param {string} uname 
	 */
	constructor(seatName, uid, uname) {
		this.seatName = seatName;
		this.uid = uid;
		this.uname = uname;
	}
}

export {
	Lottery
};
